{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c6fc1426",
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.session import GsSession\n",
    "\n",
    "GsSession.use(client_id=None, client_secret=None, scopes=('run_analytics',))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63822e50",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create what if trade\n",
    "\n",
    "from gs_quant.instrument import FXOption, FXEuropeanKnockout\n",
    "from gs_quant.markets.portfolio import Portfolio, Grid\n",
    "from gs_quant.markets import PricingContext, LiveMarket\n",
    "from gs_quant.risk import FXSpot, FXAnnualImpliedVol\n",
    "import datetime as dt\n",
    "import pprint\n",
    "\n",
    "pp = pprint.PrettyPrinter(indent=4)\n",
    "\n",
    "# shift+tab to preview what the parameters should be\n",
    "leg = FXOption(\n",
    "    pair='EURUSD',\n",
    "    expiration_date='3m',\n",
    "    strike_price='25D',\n",
    "    notional_amount='50m',\n",
    "    premium=0,\n",
    "    option_type='Call',\n",
    "    buy_sell='Buy',\n",
    ")\n",
    "pp.pprint(leg.as_dict())\n",
    "\n",
    "leg.price()\n",
    "\n",
    "# by default the pricing is done as of today with last nights close rolled to today"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6a273f03",
   "metadata": {},
   "outputs": [],
   "source": [
    "# if we wanted to price a trade historically in time we can do that using an historical pricing context\n",
    "\n",
    "from gs_quant.markets import HistoricalPricingContext\n",
    "\n",
    "with HistoricalPricingContext(\n",
    "    start=dt.date(2025, 1, 3), end=dt.date(2025, 4, 1), visible_to_gs=True, market_data_location='NYC'\n",
    "):\n",
    "    h = leg.price()\n",
    "h.result().plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ecafb3e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# when we price an Spot+1% trade historically what does that mean.  Well that depends on whether you have resolved the trade\n",
    "# or not.\n",
    "# If not then the trade will be moving in time, on each day a new 3m spot+1% option was priced.  We may want to fix the\n",
    "# trade as at the start date\n",
    "\n",
    "with PricingContext(pricing_date=dt.date(2025, 1, 3)):\n",
    "    leg2 = leg.resolve(in_place=False)\n",
    "leg2 = leg2.result()\n",
    "\n",
    "# compare the unresolved trade to the resolved one.\n",
    "pp.pprint(leg2.as_dict())\n",
    "\n",
    "\n",
    "from gs_quant.risk import Price\n",
    "\n",
    "with HistoricalPricingContext(start=dt.date(2025, 1, 3), end=dt.date(2025, 4, 1)):\n",
    "    h2 = leg2.calc(Price)\n",
    "h2.result().plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cfeef04-117b-42e6-ab15-16b982e06d87",
   "metadata": {},
   "outputs": [],
   "source": [
    "#  We can price live by amending the pricing context as well\n",
    "\n",
    "with PricingContext(market=LiveMarket()):\n",
    "    s = leg.calc(FXSpot)\n",
    "s.result()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7530294f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# we have a concept of a portfolio which behaves similarly to a trade so you can pack many trades into one object and price that.  Also shows how other metrics can be referenced and called.\n",
    "\n",
    "from gs_quant.common import InOut\n",
    "from gs_quant.risk import FXQuotedDelta\n",
    "\n",
    "port = Portfolio(\n",
    "    [\n",
    "        FXEuropeanKnockout(\n",
    "            pair='GBPUSD',\n",
    "            expiration_date='3m',\n",
    "            strike_price='1.25',\n",
    "            knock_in_or_out=InOut.Out,\n",
    "            barrier_level=f'{1.10 + x / 100}',\n",
    "            name=f'{x}',\n",
    "        )\n",
    "        for x in range(25, 35)\n",
    "    ]\n",
    ")\n",
    "\n",
    "\n",
    "print(len(port))\n",
    "r = port.calc((FXQuotedDelta, FXAnnualImpliedVol))\n",
    "r.to_frame()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f8da928-96b4-4881-a06f-571b31251fe0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# screeners are a popular usecase and there is a type of portfolio called a grid which can aid in construction of 2d grids of prices\n",
    "\n",
    "# grids take an example trade and then two parameters and the possible values of each\n",
    "grid = Grid(FXOption(pair='EURUSD', premium=0), 'strike_price', ['10d', '20d'], 'expiration_date', ['1m', '3m', '6m'])\n",
    "\n",
    "r = grid.price()\n",
    "r.to_frame()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "573b76f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# we can define and apply scenarios to our pricing\n",
    "\n",
    "from gs_quant.risk import MarketDataPattern, MarketDataShock, MarketDataShockType, MarketDataShockBasedScenario\n",
    "\n",
    "parallel_shock = MarketDataShockBasedScenario(\n",
    "    shocks={\n",
    "        MarketDataPattern(mkt_type='FX Vol', mkt_asset='USD/EUR', mkt_class='ATM VOL'): MarketDataShock(\n",
    "            MarketDataShockType.Absolute, 0.0001\n",
    "        )\n",
    "    }\n",
    ")\n",
    "\n",
    "with PricingContext(dt.date(2025, 2, 18)):\n",
    "    orig_price = leg.price()\n",
    "    with parallel_shock:\n",
    "        res = leg.price()\n",
    "print(f'original price: {orig_price.result():.4f}')\n",
    "print(f'shock price: {res.result():.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ffe240d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# as well as pricing historically we can project the market forward and price in the future.\n",
    "\n",
    "from gs_quant.risk import RollFwd\n",
    "\n",
    "carry_scenario = RollFwd(date=dt.date(2025, 3, 15), realise_fwd=True)\n",
    "with carry_scenario:\n",
    "    res = leg.price()\n",
    "\n",
    "print(f'roll fwd price: {res:.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4672f11",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# sometimes you may want to look at the market data used in a pricing request.\n",
    "\n",
    "from gs_quant.markets import PricingContext\n",
    "\n",
    "with PricingContext(dt.date(2024, 4, 4)):\n",
    "    market = leg.market()\n",
    "market.result().market_data_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39bc9d3e",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "%%time\n",
    "# loading from a dataset\n",
    "\n",
    "\n",
    "from gs_quant.data import Dataset\n",
    "import datetime as dt\n",
    "\n",
    "\n",
    "dataset = Dataset('MACRO_EVENTS_CALENDAR')\n",
    "dataset.get_data(dt.datetime(2024, 12, 1), dt.datetime(2025, 12, 31), eventName='ISM Manufacturing PMI')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82f92f0e-a699-4835-953e-8f0d0b8b9f67",
   "metadata": {},
   "outputs": [],
   "source": [
    "irfwd_eur = Dataset('IR_SWAP_RATES').get_data(\n",
    "    dt.date(2025, 1, 3),\n",
    "    dt.date(2025, 1, 29),\n",
    "    currency='EUR',\n",
    "    effectiveTenor='1y',\n",
    "    terminationTenor='10y',\n",
    "    floatingRateOption='EUR-EURIBOR-TELERATE',\n",
    "    floatingRateDesignatedMaturity='6m',\n",
    "    clearingHouse='LCH',\n",
    ")\n",
    "irfwd_eur['rate']"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
